home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The PC-SIG Library 10
/
The PC-Sig Library - Shareware for the IBM PC and Compatibles (PC-SIG)(Tenth Edition Disks 1-2804)(1991).iso
/
PC_SIGCD
/
12
/
0
/
DISK1205.ZIP
/
IDCUTIL
/
IDCUTIL.EXE
/
LETTER.ASM
< prev
next >
Wrap
Assembly Source File
|
1988-12-12
|
14KB
|
570 lines
;================================================================
;Program : LETTER.ASM |
;Author : Gary Conway |
;Created : 09.08.88 |
;Update : 12.11.88 |
;Version : 1.1 |
;Notice : Copyright 1988 Infinity Design Concepts |
; Inc. all rights reserved |
; 1052 Parkway Drive |
; Louisville, Kentucky 40217 |
; 502-636-1234 |
;================================================================
comment |
This source code is copyrighted material and may not be used
or reproduced for financial gain without the expressed written
consent of the author.
|
; this program will print addresses on envelopes on the HP Laserjet series ][
; or brother HL-8 laser printers in landscape mode. The envelope will be
; inserted in the manual feed tray
; NOTE: The original source code is set for business envelopes, if you have
; another size envelope that you wish to use, then you must change
; this file and assemble it again. You will have to change the
; TopMargin and LeftMargin variables.
comment |
; ASSEMBLE with the following commands.
masm letter;
link letter;
|
MajVer Equ "1"
MinVer Equ "0"
; define a macro for positioning the cursor on the screen
CURPOS Macro ROW,COL,PAGE ;;macro to set cursor to desired screen pos.
Mov DH,ROW
Mov DL,COL
Mov BH,PAGE
Mov AH,2
Int 10H ;; use BIOS routine (slow)
Endm
DSEG Segment para public 'DATA'
CR Equ 13 ; CR may now be used instead of 13
LF Equ 10 ; LF " " " " " " 10
ESCchar Equ 27 ; ESC (ESCape) character
; define some variables for the built-in routines
CurShape DW ? ; save shape of cursor when pgm. called
Bksp_ DB 8,' ',8,0
CONSBUFF DB 100,00,100 DUP (' ')
Print_String Label Byte
; DB 1Bh,0Dh,"H" ; set to emulate HP laserjet+
; (used ONLY on brother HL-8)
DB 1Bh,"&l3H" ; set for envelopes
DB 1Bh,"&l1O" ; set to landscape mode
DB 0 ; terminator
Reset DB 1Bh,"E",0 ; reset printer string
Control_C DB "Control-C to abort",cr,lf
DB 15 dup(" ")
DB "If you find this program useful, please register!",0
SignOn DB "Ver. ",MajVer,".",MinVer," "
DB "Copyright 1988, Infinity Design Concepts, Inc. all rights reserved",cr,lf,lf
DB 3 dup(" ")
DB "This program will print envelopes on the"
DB " HP LaserJet+ or compatible printer.",cr,lf
DB 9 dup(" ")
DB "Note that the envelopes will be fed thru the manual tray",cr,lf
DB 20 dup(" ")
DB "and printed in the LandScape mode."
DB cr,lf,lf,lf,0
NotReady DB cr,lf,7,"Printer Not Ready... Hit ENTER.",7,cr,lf,0
Blanks DB " ",0
; the prompts
Name1 DB "Enter Name ..................: ",0
Add1 DB "Enter First Line of Address .: ",0
Add2 DB "Enter Second Line of Address : ",0
City DB "Enter City ..................: ",0
State DB "Enter State .................: ",0
Zip DB "Enter Zip ...................: ",0
Attn DB "Enter Attn of Name ..........: ",0
; the following information is what is actually printed
Pr_name DB 50 dup(0)
Pr_add1 DB 50 dup(0)
Pr_add2 DB 50 dup(0)
Pr_City DB 50 dup(0)
Pr_State DB 50 dup(0)
Pr_Zip DB 50 dup(0)
Attn_Pr DB "Attn: "
Pr_Attn DB 50 dup(0)
DSEG Ends
; define the CODE segment
CSEG Segment para public 'CODE'
ASSUME CS:CSEG,SS:ASTACK
ENTPT Proc ;Start of Code Execution
Mov AX,DSEG ; set up segment addresses
Mov DS,AX ; data seg.
Mov ES,AX ; extra seg.
ASSUME DS:DSEG,ES:DSEG
Call SaveCursor ; save cursor shape
Call Clrsc ; clear the screen
Call Curoff ; turn cursor off
CurPos 1,0,0
Lea SI,SignOn
Call Ilprt ; print signon message
CurPos 18,31,0 ; put cursor at 18,31
Lea SI,Control_C
Call Ilprt ; print abort msg.
CurPos 9,0,0 ; put cursor at 9,0
Call Curon ; turn cursor back on
; get name
Lea SI,Name1
Call Ilprt ; print name prompt
Call Rdcons ; get string from user
Lea SI,Consbuff +2
Lea DI,Pr_name ; destination for printing
Call Insert ; put user string there
Call Crlf ; send crlf to screen
; get address line 1
Lea SI,Add1
Call Ilprt ; print addr.line 1 prompt
Call Rdcons ; get string from user
Lea SI,Consbuff +2
Lea DI,Pr_add1
Call Insert ; store it
Call Crlf
; get address line 2
Lea SI,Add2
Call Ilprt
Call Rdcons
Lea SI,Consbuff +2
Lea DI,Pr_add2
Call Insert
Call Crlf
; get city
Lea SI,City
Call Ilprt
Call Rdcons
Lea SI,Consbuff +2
Lea DI,Pr_city
Call Insert
Call Crlf
; get state
Lea SI,State
Call Ilprt
Call Rdcons
Lea SI,Consbuff +2
Lea DI,Pr_state
Call Insert
Call Crlf
; get zip
Lea SI,Zip
Call Ilprt
Call Rdcons
Lea SI,Consbuff +2
Lea DI,Pr_zip
Call Insert
Call Crlf
; get attn of
Lea SI,Attn
Call Ilprt
Call Rdcons
Lea SI,Consbuff +2
Lea DI,Pr_attn
Call Insert
Test_Ptr: Mov AH,2
Xor DX,DX
Int 17h ; read printer status
Test AH,01001001b ; bit 7 = busy
; bit 5 = out of paper
; bit 3 = I/O error
; bit 0 = time out
Jz Ptr_Ready
CurPos 20,0,0
Lea SI,NotReady
Call Ilprt
Mov AH,8
Int 21h ; wait for character and test again
Jmp Short Test_Ptr
Ptr_Ready: CurPos 20,0,0
Lea SI,Blanks
Call Ilprt ; remove error msg if there
Lea SI,Print_String
Call Print ; set printer to proper mode
Call Print_CRs ; print 20 crlf's
Call Print_Env ; print the envelope
Call Pcrlf ; carriage return linefeed
Mov AL,12
Call Prchar ; send forfeed
Lea SI,Reset
Call Print ; reset printer to control
; panel defaults
Exit: CurPos 20,0,0 ; put cursor at 20,0
Call Curon ; turn cursor on
Mov AX,4C00h ; return to DOS
Int 21h
;--------------------------------------------------------------------------
; SUPPORT ROUTINES
;--------------------------------------------------------------------------
;------------------------------------------------------------------
; THIS ROUTINE DETERMINES WHERE THE TEXT ON THE ENVELOPE WILL START
; AS MEASURED FROM THE TOP OF THE ENVELOPE
; If you wish to change this distance, change TopMargin below to
; whatever works for you
; send 20 carriage return and linefeeds to the printer
;------------------------------------------------------------------
TopMargin Equ 20
Print_CRs Proc
Mov CX,TopMargin ; send this many crlf's
Pr_1: Push CX
Call Pcrlf
Pop CX
Loop Pr_1
Ret
Print_CRs Endp
;------------------------------------------------------------------
; THIS ROUTINE DETERMINES WHERE THE TEXT ON THE ENVELOPE WILL START
; AS MEASURED FROM THE LEFT MARGIN. If you wish to change this
; distance, change LeftMargin below.
; send 37 spaces to the printer
;-------------------------------------------------------------------
LeftMargin Equ 37 ; left margin
Print_Space Proc
Mov CX,LeftMargin ; this many spaces
Pr_Sp: Push CX ; save it
Mov AL," "
Call Prchar ; send space to printer
Pop CX
Loop Pr_Sp ; loop till done
Ret
Print_Space Endp
;---------------------------------------
; this procedure will print the envelope
;---------------------------------------
Print_Env Proc
Call Print_Space ; print 37 spaces
Lea SI,PR_name ; point to name string
Cmp Byte Ptr[SI],0 ; empty ?
Je Empt_1 ; yup, skip it
Call Print ; else, print the string
Call Pcrlf ; and a crlf
Call Print_Space ; print 37 spaces
; print address line 1
Empt_1: Lea SI,Pr_add1 ; point to addr line 1 string
Cmp Byte Ptr [SI],0 ; empty ?
Je Empt_2 ; yup, skip it
Call Print ; else print it
Call Pcrlf ; and a crlf
Call Print_Space ; print 37 spaces
; print address line 2, if not empty
Empt_2: Lea SI,Pr_add2 ; point to addr line 2 string
Cmp byte Ptr [SI],0 ; string empty ?
Je Empt_3 ; yup, skip it
Call Print ; else, print it
Call Pcrlf ; and a crlf
Call Print_Space ; print 37 spaces
; print city,state, zip
Empt_3: Lea SI,Pr_city ; point to city string
Call Print ; print it
Mov AL,","
Call Prchar ; and a comma
Mov AL," "
Call Prchar ; and a space
Lea SI,Pr_State
Call Print ; print state
Mov AL," "
Call Prchar ; and a space
Lea SI,Pr_Zip
Call Print ; print zip code
Call Pcrlf
; print attn if not empty
Cmp Byte Ptr [Pr_Attn],0 ; user string empty ?
Je Empt_4 ; yup, skip it
Call Print_Space ; print 37 spaces
Lea SI,Attn_Pr ; point to "Attn:" string
Call Print ; and print it
Empt_4: Ret
Print_Env Endp
;-----------------------------------------------
; send a carriage return and linefeed to printer
;-----------------------------------------------
Pcrlf Proc
Mov AL,CR
Call Prchar
Mov AL,LF
Call Prchar
Ret
Pcrlf Endp
;-----------------------------------
; send ASCIZ string in SI to printer
;-----------------------------------
Print Proc
Lodsb ; get character
Or AL,AL ; is it zero ?
Je Pr_Dne ; yup, then done
Call Prchar ; else, print the char
Jmp Short Print ; keep going till zero
Pr_Dne: Ret
Print Endp
;---------------------------
; send char in AL to printer
;---------------------------
Prchar Proc
Push SI
Mov DL,AL
Mov AH,5
Int 21h ; send char in DL to printer
Pop SI
Ret
Prchar Endp
;---------------------------------------------------------------------
; this procedure will move the string from SI to DI and stop with the
; CR character and replace it with a zero
;---------------------------------------------------------------------
Insert Proc
Lodsb ; get source character
Or AL,AL ; terminator ?
Jz All_Done ; then quit
Stosb ; else, store it
Jmp Short Insert ; do em all
All_Done: Ret
Insert Endp
;-----------------
; clear the screen
;-----------------
Clrsc Proc
Mov AX,0600h ; scroll function
Mov BH,15 ; clear attribute
Xor CX,CX ; upper left corner
Mov DX,184Fh ; lower right corner
Int 10h ; BIOS clear screen
Ret
Clrsc Endp
;--------------------------------------------------
; send a carriage return and linefeed to the screen
;--------------------------------------------------
Crlf Proc
Mov AL,CR
Call Pchar
Mov AL,LF
Call Pchar
Ret
Crlf Endp
;--------------------------------------------------
; send an ASCIIZ string to the screen, SI is pntr
;--------------------------------------------------
Ilprt Proc ; on exit SI points to 0 terminator
Lodsb ; get character
Or AL,AL ; is it terminator ?
Jz ILK1 ; yup, then done
Call Pchar ; else print char on screen
Jmp Short Ilprt ; do em all
ILK1: Ret
Ilprt Endp
;---------------------------
; print char in AL on screen
;---------------------------
Pchar Proc
Push CX ; save some regs
Push SI
Push DI
Mov AH,2
Mov DL,AL ; move char into DL
Int 21H ; put on screen
Pop DI
Pop SI
Pop CX
Ret
Pchar Endp
;--------------------
; turn the cursor off
;--------------------
Curoff Proc
Push AX
Mov CX,2000H
Mov AH,1
Int 10h
Pop AX
Ret
Curoff Endp
;------------------------
; turn the cursor back on
;------------------------
Curon Proc
Push AX
Mov CX,[CurShape] ; retrieve cursor shape
Mov AH,1 ; set cursor mode
Int 10h
Pop AX
Ret
Curon Endp
;----------------------------------------------------------------
; save the current shape of the cursor so when we turn it back on
; it is still the same. Note that this routine should really be
; called before turning the cursor OFF the first time and should
; definitely be called before calling CURON
;----------------------------------------------------------------
SaveCursor Proc ; get cursor start and stop lines
Push ES ; from 0040:0060 and save for
Mov AX,40h ; cursor on routine
Mov ES,AX
Mov CX,ES:[60H]
Pop ES
Mov [CurShape],CX
Ret
SaveCursor Endp
;---------------------------------------
; read string from console into CONSBUFF
;---------------------------------------
RDcons Proc
Call Conbfset ; blank the buffer
Lea DI,Consbuff +2 ; dest buffer
Xor CX,CX ; char count
GetChr: Xor AH,AH ; BIOS wait for char
Int 16h
Or AH,AH
Jz GetChr ; no extended codes
Cmp AL,3 ; ^C
Jne Not_C
Jmp Exit ; user aborted
Not_C: Cmp AL,13
Je EndInput ; CR allowed (end)
Cmp AL,8
Je BkSpace ; backspace allowed (edit)
Cmp AL,' '
Jb GetChr ; no other control codes allowed
Cmp AL,7Bh
Jae GetChr ; no graphics either
PutChr: Call Pchar
Stosb ; put char in buffer
Inc CX ; increment out count
Cmp CX,80 ; at max ?
Jb GetChr ; if < 80, then get more
Jmp Short EndInput
BkSpace: Cmp CX,0
Je GetChr ; no chars to delete
Push DI
Push CX
Lea SI,Bksp_ ; print 8,' ',8
Call Ilprt
Pop CX
Pop DI
Dec DI ; decr buffer ptr
Dec CX ; decr num chars entered
Jmp GetChr
EndINput: Xor AL,AL
Stosb ; add another delimiter
Mov Consbuff +1,CL ; install num chars entered
Ret
Conbfset Proc ; set console buffer
Lea DI,Consbuff+2
Mov CX,80 ; pad 80 blanks
Mov AL,' '
Rep Stosb ; store all blanks
Ret
Conbfset Endp
RDcons Endp
ENTPT Endp
CSEG Ends
ASTACK Segment para stack 'STACK'
DB 25 DUP("HAYSTACK ") ; stack area
ASTACK Ends
End ENTPT